From 5d12c5b4966fa10011a6f6a559e7a73531d535b8 Mon Sep 17 00:00:00 2001 From: Sehny Date: Tue, 27 Jun 2017 19:51:56 +0200 Subject: [PATCH] Infer paths as well as names for binaries --- src/cargo/util/toml.rs | 30 +++++++++++++++++++++++------- tests/build.rs | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/cargo/util/toml.rs b/src/cargo/util/toml.rs index 9cf1f5386..b70b102f7 100644 --- a/src/cargo/util/toml.rs +++ b/src/cargo/util/toml.rs @@ -83,13 +83,12 @@ fn try_add_mains_from_dirs(files: &mut Vec, root: PathBuf) { // Filter only directories .filter(|i| { i.file_type().map(|f| f.is_dir()).unwrap_or(false) - // Convert DirEntry into PathBuf and append "main.rs" + // Convert DirEntry into PathBuf and append "main.rs" }).map(|i| { - i.path().join("main.rs") + i.path().join("main.rs") // Filter only directories where main.rs is present - }).filter(|f| { - f.as_path() - .exists() + }).filter(|f| { + f.as_path().exists() }).collect(); files.extend(new); } @@ -532,7 +531,12 @@ fn inferred_bin_targets(name: &str, layout: &Layout) -> Vec { // if the path ends with main.rs it is probably a directory, but it can also be // a file directly inside src/bin if parent.ends_with("src/bin") { - bin.file_stem().and_then(|s| s.to_str()).map(|f| f.to_string()) + // This would always return name "main" + // Fixme: Is this what we want? based on what @matklad said, I don't think so + // bin.file_stem().and_then(|s| s.to_str()).map(|f| f.to_string()) + + // This seems to be the right solution based on the inferred_bin_paths function + Some(name.to_string()) } else { parent.file_stem().and_then(|s| s.to_str()).map(|f| f.to_string()) } @@ -1481,7 +1485,7 @@ fn inferred_bin_path(bin: &TomlBinTarget, package_root: &Path, bin_len: usize) -> PathBuf { // here we have a single bin, so it may be located in src/main.rs, src/foo.rs, - // srb/bin/foo.rs or src/bin/main.rs + // src/bin/foo.rs, src/bin/foo/main.rs or src/bin/main.rs if bin_len == 1 { let path = Path::new("src").join(&format!("main.rs")); if package_root.join(&path).exists() { @@ -1500,6 +1504,12 @@ fn inferred_bin_path(bin: &TomlBinTarget, return path.to_path_buf() } + // check for the case where src/bin/foo/main.rs is present + let path = Path::new("src").join("bin").join(bin.name()).join(&format!("main.rs")); + if package_root.join(&path).exists() { + return path.to_path_buf() + } + return Path::new("src").join("bin").join(&format!("main.rs")).to_path_buf() } @@ -1509,6 +1519,12 @@ fn inferred_bin_path(bin: &TomlBinTarget, return path.to_path_buf() } + // we can also have src/bin/foo/main.rs, but the former one is preferred + let path = Path::new("src").join("bin").join(bin.name()).join(&format!("main.rs")); + if package_root.join(&path).exists() { + return path.to_path_buf() + } + if !has_lib { let path = Path::new("src").join(&format!("{}.rs", bin.name())); if package_root.join(&path).exists() { diff --git a/tests/build.rs b/tests/build.rs index 096927a6b..bbc1ca1b1 100644 --- a/tests/build.rs +++ b/tests/build.rs @@ -3285,7 +3285,6 @@ fn dirs_in_bin_dir_with_main_rs() { .file("src/main.rs", "fn main() {}") .file("src/bin/bar.rs", "fn main() {}") .file("src/bin/bar2.rs", "fn main() {}") - .file("src/bin/main.rs", "fn main() {}") .file("src/bin/bar3/main.rs", "fn main() {}") .file("src/bin/bar4/main.rs", "fn main() {}"); @@ -3295,5 +3294,41 @@ fn dirs_in_bin_dir_with_main_rs() { assert_that(&p.bin("bar2"), existing_file()); assert_that(&p.bin("bar3"), existing_file()); assert_that(&p.bin("bar4"), existing_file()); - assert_that(&p.bin("main"), existing_file()); +} + +#[test] +fn dir_and_file_with_same_name_in_bin() { + // this should fail, because we have two binaries with the same name + let p = project("bar") + .file("Cargo.toml", r#" + [package] + name = "bar" + version = "0.1.0" + authors = [] + "#) + .file("src/main.rs", "fn main() {}") + .file("src/bin/foo.rs", "fn main() {}") + .file("src/bin/foo/main.rs", "fn main() {}"); + + // TODO: This should output the error from toml.rs:756 + assert_that(p.cargo_process("build"), execs().with_status(101)); +} + +#[test] +fn inferred_path_in_src_bin_foo() { + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "foo" + version = "0.1.0" + authors = [] + + [[bin]] + name = "bar" + # Note, no `path` key! + "#) + .file("src/bin/bar/main.rs", "fn main() {}"); + + assert_that(p.cargo_process("build"), execs().with_status(0)); + assert_that(&p.bin("bar"), existing_file()); } -- 2.30.2